package gui;


import client.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import java.util.Vector;
import java.util.Collections;
import java.util.Hashtable;
import msg.*;

/**
 *
 * @author tomek
 */
public class UsersListGui extends JFrame implements ActionListener, ListSelectionListener, MouseListener {

    private UsersList myUsersList;
    
    private JList jlist;
    private JScrollPane listScrollPane;
    private JMenu statusMenu;
    private JPopupMenu popup;
    private TrayIcon tray;
    static Vector usersVector;          //do przechowywania listy uzytkownikow
    static DefaultListModel listModel;  //do wyswietlania listy uzytkownikow (latwiejsza modyfikacja)
    static Hashtable convsTable;
    ImageIcon icon;     //ikony przy menu
    
    
    public UsersListGui(UsersList u, Vector<User> users) {
        super(Client.getLogin());
        myUsersList = u;
        if (users != null) usersVector = users;
        else usersVector = new Vector<User>();
        convsTable = new Hashtable();
        
        setLayout(new BorderLayout());
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        
        
        initList();
        sortList();

        Connection c = new Connection(1028);
        if(c.status(new MsgStatus(Client.getLogin(), Client.getHash(), User.AVAILABLE)) == 1) {
            setStatus(User.AVAILABLE);
            setTrayIcon(Menu.AVAILABLE.imgURL(), Menu.AVAILABLE.toString());
        }
        else {
            System.out.println("Nie udało sie zalogowac");
            setStatus(User.NOTAVAILABLE);
            setTrayIcon(Menu.NOTAVAILABLE.imgURL(), Menu.NOTAVAILABLE.toString());
        }
        
        
        JButton statusButton = new JButton("Status");
        statusButton.setVisible(true);
        add(statusButton, BorderLayout.PAGE_END);
        statusButton.addActionListener(this);
        
//        statusMenu = createStatusMenu();
//        popup = createPopupMenu();

//        jlist.add(popup);
//        popup.setVisible(true);
        
    }
    
    /** enum type with menu's jlist and paths to icons */
    public enum Menu {
        //GENERAL MENU
            ADD ("Dodaj kontakt", "../img/16x16/add.png"),
            EDIT ("Edytuj kontakt", "../img/16x16/edit.png"),
            REMOVE ("Usun kontakt", "../img/16x16/minus.png"),
            REGISTER ("Zarejestruj konto", "../img/16x16/user.png"),
            HISTORY ("Historia", "../img/16x16/calendar_full.png"),
            OPTIONS ("Ustawienia", "../img/16x16/tools.png"),
            EXIT ("Zakoncz", "../img/16x16/shut_down.png"),
       //STATUS MENU
            AVAILABLE ("Dostepny", "../img/16x16/play.png"),
            BUSY ("Zajety", "../img/16x16/pause.png"),
            NOTAVAILABLE("Niedostepny", "../img/16x16/stop.png"),
       //HELP MENU
            HELP ("Help", "../img/16x16/help.png"),
            ABOUT ("About", "../img/16x16/info.png")
            ;
            
            private String opis;
            private String imgURL;
            
            Menu (String opis, String imgURL) {
                this.opis = opis;
                this.imgURL = imgURL;
            }
            
            public String opis() {return opis;}
            public String imgURL() {return imgURL;}
            
    }
    
    public Hashtable getConvsTabel() { return convsTable; }

    public Vector getUsersVector() { return usersVector; }
    
    public void setTrayIcon(String s, String t) {
        icon = createIcon(s);
        if (tray == null) {
            tray = new TrayIcon(icon.getImage());
            tray.setToolTip(t);
            try {
                SystemTray.getSystemTray().add(tray);
            } catch (AWTException e) {
                System.err.println("Blad przy dodawaniu TrayIcon.");
            }
        }
        else {
            tray.setImage(icon.getImage());
            tray.setToolTip(t);
        }
    }

    public void setStatus(byte s) {
        Client.setStatus(s);
        System.out.println("Status: " + s);
    }
    
    public JMenuBar createMenuBar() {
        
        JMenuBar menuBar;
        JMenu menu;
        JMenuItem menuItem;
        
        menuBar = new JMenuBar();
        
//GENERAL MENU        
        menu = new JMenu("General");
        menu.setMnemonic(KeyEvent.VK_G);
        menuBar.add(menu);
        
        icon = createIcon(Menu.ADD.imgURL());
        menuItem = new JMenuItem(Menu.ADD.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.ADD.toString());
        
        icon = createIcon(Menu.EDIT.imgURL());
        menuItem = new JMenuItem(Menu.EDIT.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.EDIT.toString());
        
        icon = createIcon(Menu.REMOVE.imgURL());
        menuItem = new JMenuItem(Menu.REMOVE.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.REMOVE.toString());
        
        icon = createIcon(Menu.REGISTER.imgURL());
        menuItem = new JMenuItem(Menu.REGISTER.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.REGISTER.toString());
            
        icon = createIcon(Menu.HISTORY.imgURL());
        menuItem = new JMenuItem(Menu.HISTORY.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.HISTORY.toString());
        
        icon = createIcon(Menu.OPTIONS.imgURL());
        menuItem = new JMenuItem(Menu.OPTIONS.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.OPTIONS.toString());
        
        
        icon = createIcon(Menu.EXIT.imgURL());
        menuItem = new JMenuItem(Menu.EXIT.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.EXIT.toString());
        
//STATUS MENU        
        menu = new JMenu("Status");
        menu.setMnemonic(KeyEvent.VK_S);
        menuBar.add(menu);
        
        icon = createIcon(Menu.AVAILABLE.imgURL());
        menuItem = new JMenuItem(Menu.AVAILABLE.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.AVAILABLE.toString());
        
        icon = createIcon(Menu.BUSY.imgURL());
        menuItem = new JMenuItem(Menu.BUSY.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.BUSY.toString());
        
        icon = createIcon(Menu.NOTAVAILABLE.imgURL());
        menuItem = new JMenuItem(Menu.NOTAVAILABLE.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.NOTAVAILABLE.toString());
        
        
//HELP MENU        
        menu = new JMenu("Help");
        menu.setMnemonic(KeyEvent.VK_H);
        menuBar.add(menu);
        
        icon = createIcon(Menu.HELP.imgURL());
        menuItem = new JMenuItem(Menu.HELP.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.HELP.toString());
        
        icon = createIcon(Menu.ABOUT.imgURL());
        menuItem = new JMenuItem(Menu.ABOUT.opis(), icon);
        menu.add(menuItem);
        menuItem.addActionListener(this);
        menuItem.setActionCommand(Menu.ABOUT.toString());
        
        return menuBar;
    }


    /** Returns an popup menu*/
    public JPopupMenu createPopupMenu() {
        JPopupMenu p = new JPopupMenu();
        JMenuItem m = new JMenuItem("Dostepny");
        m.addActionListener(this);
        p.add(m);
        
        m = new JMenuItem("Zajety");
        m.addActionListener(this);
        p.add(m);
        
        m = new JMenuItem("Niedostepny");
        m.addActionListener(this);
        p.add(m);
        
        return p;
    }
    
    /** Returns an ImageIcon, or null if the path was invalid. */
    public static ImageIcon createIcon(String path) {
        java.net.URL imgURL = UsersListGui.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Sciezka do ikony " + path + " niepoprawna");
            return null;
        }
    }

    public void initList() {

        listModel = new DefaultListModel();

        for (int i=0; i<usersVector.size(); i++) {
            listModel.addElement(usersVector.get(i));
            System.out.println(((User)listModel.getElementAt(i)).present());
        }


        jlist = new JList(listModel);
        jlist.addMouseListener(this);
    
        MyListRenderer renderer = new MyListRenderer();

        jlist.setCellRenderer(renderer);
//        jlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//        jlist.setSelectedIndex(0);
        jlist.addListSelectionListener(this);
//        jlist.setVisibleRowCount(5);
//        jlist.setListData(lista);

        listScrollPane = new JScrollPane(jlist);

        this.getContentPane().add(listScrollPane, BorderLayout.CENTER);
    }

    public void updateList() {

        listModel.clear();
        for (int i=0; i<usersVector.size(); i++) {
            listModel.addElement(usersVector.get(i));
            System.out.println(((User)listModel.getElementAt(i)).present());
        }

//        listScrollPane.repaint();
    }

    public void sortList() {
        if (usersVector != null) {
            try {
                Collections.sort(usersVector);
            } catch (ClassCastException e) {
                System.err.println("Blad przy sortowaniu obiektow");
            }
        }
    }


    
// ActionListener method    
    public void actionPerformed(ActionEvent e) {
//MENU ACTIONS        
        if(e.getActionCommand().equals(Menu.ADD.toString())) {
            new AddingContact(this);
        }
        else if(e.getActionCommand().equals(Menu.REMOVE.toString())) {
            if (jlist.getSelectedValue() != null) {
                if (JOptionPane.showConfirmDialog(new JFrame(), "Czy na pewno chcesz usunąć użytkownika: " + ((User)jlist.getSelectedValue()).present(), "Usun", JOptionPane.YES_NO_OPTION) == 0) {
                    int index = jlist.getSelectedIndex();
                    usersVector.remove(index);
                    sortList();
                    updateList();
                }
            }
        }
        else if(e.getActionCommand().equals(Menu.REGISTER.toString())) {
            new Registration();
        }
        else if(e.getActionCommand().equals(Menu.HISTORY.toString())) {
            new HistoryRequest();
        }
        else if(e.getActionCommand().equals(Menu.EXIT.toString())) {
            if (JOptionPane.showConfirmDialog(new JFrame(), "Czy na pewno chcesz wyjść z programu?", "Zakoncz", JOptionPane.YES_NO_OPTION) == 0) {
                myUsersList.saveUsersList(usersVector);
                System.exit(0);
            }  
        }
        else if(e.getActionCommand().equals(Menu.AVAILABLE.toString())) {
            Connection c = new Connection(1028);
            if(c.status(new MsgStatus(Client.getLogin(), Client.getHash(), User.AVAILABLE)) == 1) {
                setStatus(User.AVAILABLE);
                setTrayIcon(Menu.AVAILABLE.imgURL(), Menu.AVAILABLE.toString());
            }
            else System.out.println("Nie udało sie zmienic statusu");
        }
        else if(e.getActionCommand().equals(Menu.BUSY.toString())) {
            Connection c = new Connection(1028);
            if(c.status(new MsgStatus(Client.getLogin(), Client.getHash(), User.BUSY)) == 1) {
                setStatus(User.BUSY);
                setTrayIcon(Menu.BUSY.imgURL(), Menu.BUSY.toString());
            }
            else System.out.println("Nie udało sie zmienic statusu");
        }
        else if(e.getActionCommand().equals(Menu.NOTAVAILABLE.toString())) {
            Connection c = new Connection(1028);
            if(c.status(new MsgStatus(Client.getLogin(), Client.getHash(), User.NOTAVAILABLE)) == 1) {
                setStatus(User.NOTAVAILABLE);
                setTrayIcon(Menu.NOTAVAILABLE.imgURL(), Menu.NOTAVAILABLE.toString());
            }
            else System.out.println("Nie udało sie zmienic statusu");
        }
        
    }
    
//ListSelectionListener method
    public void valueChanged(ListSelectionEvent e) {
        if (jlist.getSelectedIndex() == -1) {
            //
        }
    }
    
//MouseListsner methods
    public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 2) {
            final int index = jlist.locationToIndex(e.getPoint());
            final String u = ((User)usersVector.get(index)).present();
            Conversation conv;
            
            if(convsTable.containsKey(u)) {
                conv = (Conversation)convsTable.get(u);
                conv.getGui().setVisible(true);
            }
            else {
                convsTable.put(u, new Conversation(u));
            }
//            System.out.println("Double clicked on Item " + index + " " + ((User)usersVector.get(index)).present());            
        }
    }
    public void mouseExited(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    
    
    public void showGui() {
      
        setIconImage(createIcon("../img/16x16/target.png").getImage());
        
        setJMenuBar(createMenuBar());
       
        pack();
        setVisible(true);
   } 
    
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       //javax.swing.SwingUtilities.invokeLater(new Runnable() {public void run(){showGui();}}); 
    }
    
    class MyListRenderer extends JLabel implements ListCellRenderer {
        protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
        
        public MyListRenderer() {
            setOpaque(true);
            
        }
        
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            
            JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            User user = (User) value;
            ImageIcon available = createIcon(Menu.AVAILABLE.imgURL());
            ImageIcon busy = createIcon(Menu.BUSY.imgURL());
            ImageIcon notavailable = createIcon(Menu.NOTAVAILABLE.imgURL());
          
            switch(user.getStatus()) {
                case User.AVAILABLE:
                    renderer.setIcon(available);
                    break;
                case User.BUSY:
                    renderer.setIcon(busy);
                    break;
                case User.NOTAVAILABLE:
                    renderer.setIcon(notavailable);
                    break;
                default:
                    renderer.setIcon(notavailable);
                    break;
            }
            renderer.setText(user.present());
            return renderer;
        }
    }
}
